/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// (c) 2018, Mariusz Nowak
// SPDX-License-Identifier: ISC
// Derived from https://github.com/medikoo/lru-queue
export function lruQueue(limit) {
  var size = 0;
  var base = 1;
  var queue = Object.create(null);
  var map = Object.create(null);
  var index = 0;

  var del = function del(id) {
    var oldIndex = map[id];
    if (!oldIndex) return;
    delete queue[oldIndex];
    delete map[id];
    --size;
    if (base !== oldIndex) return;

    if (!size) {
      index = 0;
      base = 1;
      return;
    }

    while (!hasOwnProperty.call(queue, ++base)) {
      continue;
    }
  };

  limit = Math.abs(limit);
  return {
    hit: function hit(id) {
      var oldIndex = map[id];
      var nuIndex = ++index;
      queue[nuIndex] = id;
      map[id] = nuIndex;

      if (!oldIndex) {
        ++size;
        if (size <= limit) return undefined;
        id = queue[base];
        del(id);
        return id;
      }

      delete queue[oldIndex];
      if (base !== oldIndex) return undefined;

      while (!hasOwnProperty.call(queue, ++base)) {
        continue;
      }

      return undefined;
    },
    delete: del,
    clear: function clear() {
      size = index = 0;
      base = 1;
      queue = Object.create(null);
      map = Object.create(null);
    }
  };
}